/*Universidad del Valle de Guatemala
 * Algoritmos y Estructura de Datos
 * Sara López 12050
 * Matías Vasquez 12186
 * Sección: 21
 * Java Class: BinaryTree
 */

/**
 *
 * @author saralopez
 */


public class HuffmanTree implements Comparable {
    BinaryTree root; 
    int totalWeight; 
    int count=-1;    

    
    // Constructor
    public HuffmanTree(Leaf e)
    {
        root = new BinaryTree(e);
        totalWeight = e.frequency;
    }

   
    
    //pre: left y right no deben ser null
    //post: une dos árboles y la frecuencia con la que aparecen los valores similares en los nodos
    
    public HuffmanTree(HuffmanTree left, HuffmanTree right)
    {
        this.totalWeight = left.totalWeight + right.totalWeight;
        root = new BinaryTree(null,left.root,right.root);
    }

    
    // pre: other no debe ser null
    // post: regresa la cantidad de valores parecidos encontrados
    
    public int compareTo(Object other)
    {
        HuffmanTree that = (HuffmanTree)other;
        return this.totalWeight - that.totalWeight;
    }

    // pre:
    // post: regresa true si son iguales de lo contrario regresa false
    
    public boolean equals(Object that) {
        return this == that;
    }
    
    // pre:
    // post: Imprime cadenas respecto a los caracteres almacenados
    public void print()
    {
        print(this.root,"");
    }

   // pre:
   // post: Imprime r 
    protected void print(BinaryTree r, String representation)
    {
        if (!r.left().isEmpty()){
            print(r.left(),representation+"0"); // Agregar 0
            print(r.right(),representation+"1"); // Agregar 1
        } 
        else { // Leaf; imprimir codificación
            Leaf e = (Leaf)r.value();
            System.out.println("Encoding of "+e.ch+" is "+representation+" (frequency was "+e.frequency+")");            
        }   
    }
    
   //pre:
   //post: imprime caracteres asociados a números 
    public void decode(String mensaje){
        decode(this.root,mensaje);
    }
    
    //pre:
    //post: decodifica
    
    protected void decode(BinaryTree r, String message){
        count++; 
        if(count<=message.length()){
            if(!r.left().isEmpty()){
                if(count!=message.length()){
                    if(message.charAt(count)=='0'){
                        decode(r.left(),message);
                    }
                    else if(message.charAt(count)=='1'){
                        decode(r.right(),message);
                    }
                }
            } else{
                Leaf e = (Leaf)r.value();
                System.out.print(e.ch);
                count--;
                if(count!=message.length()&&count>0){
                    if(message.charAt(count)=='0'||message.charAt(count)=='1'){
                        decode(message);
                    }
                }
            }
        }     
    }    
}